#include <REGX52.H>
#include <INTRINS.H>

sbit LCD1602_EN = P2^7;
sbit LCD1602_RS = P2^6;
sbit LCD1602_WR = P2^5;

#define LCD1602_DataPort P0

/**
  * @brief   延迟40us
  * @details @11.0592MHz
  * @param   
  * @retval  
  */
void LCD1602_Delay40us(){
	unsigned char data i;
	_nop_();
	i = 15;
	while (--i);
}


void LCD1602_WriteCommand(unsigned char cmd) {
	LCD1602_RS = 0;
	LCD1602_WR = 0;
	LCD1602_DataPort = cmd;
	LCD1602_EN = 1;
	LCD1602_Delay40us();
	LCD1602_EN = 0;
	LCD1602_Delay40us();
}

void LCD1602_WriteData(unsigned char data_) {
	LCD1602_RS = 1;
	LCD1602_WR = 0;
	LCD1602_DataPort = data_;
	LCD1602_EN = 1;
	LCD1602_Delay40us();
	LCD1602_EN = 0;
	LCD1602_Delay40us();
}


void LCD1602_Init() {
	unsigned char data i, j;
	
	LCD1602_WriteCommand(0x38);	// 8位IO，2行，5x7
	LCD1602_WriteCommand(0x0C);	// 显示开，无光标，无光标闪
	LCD1602_WriteCommand(0x06);	// 读写数据后光标右移，显示屏不动
	LCD1602_WriteCommand(0x01);	// 清屏
	
	// delay 1600us
	_nop_();
	i = 3;
	j = 221;
	do
	{
		while (--j);
	} while (--i);
}

void LCD1602_SetCursor(unsigned char row, unsigned char column) {
	if (row == 1) {
		LCD1602_WriteCommand((column - 1) | 0x80);
	} else {
		LCD1602_WriteCommand((column - 1) | 0xC0);
	}
}

void LCD1602_ShowChar(unsigned char row, unsigned char column, unsigned char character) {
	LCD1602_SetCursor(row, column);
	LCD1602_WriteData(character);
}

void LCD1602_ShowString(unsigned char row, unsigned char column, unsigned char *string) {
	unsigned char i;
	LCD1602_SetCursor(row, column);
	for (i = 0; string[i] != '\0'; i++) {
		LCD1602_WriteData(string[i]);
	}
}

void LCD1602_ShowNumProcess(unsigned int num, unsigned char length, unsigned char radix) {
	unsigned char i, digits = 0, lead_flag, maxActiveLen;
	unsigned int tmp, power = 1;
	
	switch (radix) {
		case 10:
			maxActiveLen = 5;
			break;
		case 16:
			maxActiveLen = 4;
			break;
		case 2:
			maxActiveLen = 16;
			break;
		case 8:
			maxActiveLen = 6;
		break;
	}
	
	for (i = 1; i < maxActiveLen; i++)
		power *= radix;
	
	// 计算实际位数 (0有1位)
    tmp = num;
	if (tmp == 0) {
        digits = 1;
    } else {
        while (tmp) {
            digits++;
            tmp /= radix;
        }
    }
	
	// 处理长度参数有效性
    if (length == 0) return;   // 长度为0直接返回
	
	
    // 显示前导零
    for (i = digits; i < length; i++) {
        LCD1602_WriteData('0');
    }

    // 特殊处理0值
    if (num == 0) {
        LCD1602_WriteData('0');
        return;
    }

    // 显示数字（跳过前导零）
    lead_flag = 0;  // 前导零标志
    for (i = 0; i < maxActiveLen; i++) {
        tmp = num / power;
        num %= power;
		power /= radix;
        
        // 遇到非零数字后开始显示
        if (tmp != 0) {
            lead_flag = 1;
        }
        
        // 显示有效数字（包括中间零）
        if (lead_flag) {
			if (radix == 16 && tmp >= 10) {
				LCD1602_WriteData(tmp - 10 + 'A');
			} else {
				LCD1602_WriteData(tmp + '0');
			}
			if (--length <= 0)
				break;
        }
    }
}

void LCD1602_ShowNum(unsigned char row, unsigned char column, unsigned int num, unsigned char length) {
	LCD1602_SetCursor(row, column);
	LCD1602_ShowNumProcess(num, length, 10);
}

void LCD1602_ShowSignedNum(unsigned char row, unsigned char column, int num, unsigned char length) {
	LCD1602_SetCursor(row, column);
	if (num < 0) {
		LCD1602_WriteData('-');
		LCD1602_ShowNum(row, column + 1, -num, length);
		
	} else {
		LCD1602_WriteData('+');
		LCD1602_ShowNum(row, column + 1, num, length);
	}
}

void LCD1602_ShowHexNum(unsigned char row, unsigned char column, unsigned int num, unsigned char length) {
	LCD1602_SetCursor(row, column);
	LCD1602_ShowNumProcess(num, length, 16);
}

void LCD1602_ShowBinNum(unsigned char row, unsigned char column, unsigned int num, unsigned char length) {
	LCD1602_SetCursor(row, column);
	LCD1602_ShowNumProcess(num, length, 2);
}








